package com.ruleengine.compiler.impl;

import com.ruleengine.compiler.ITaskCompiler;
import com.ruleengine.compiler.exception.CompilerException;
import com.ruleengine.instruction.InstructionManager;
import com.ruleengine.instruction.InstructionSet;
import com.ruleengine.instruction.InstructionType;
import com.ruleengine.instruction.impl.ConditionInstruction;
import com.ruleengine.instruction.impl.GotoInstruction;
import com.ruleengine.task.ITask;
import com.ruleengine.task.condition.ICondition;
import com.ruleengine.task.config.TaskConfigManager;
import com.ruleengine.task.impl.WhenTask;

public class WhenTaskCompiler extends BaseCompiler<WhenTask> {

    /*
     * (non-Javadoc)
     * 
     * @see com.wx.workflow.engine.compiler.impl.BaseCompiler#comipleSubTask(com.wx.workflow.task.ITask)
     */
    @Override
    public void comipleSubTask(WhenTask task, InstructionSet instSet)
            throws CompilerException {
        // TODO Auto-generated method stub

        // 分支条件
        ICondition con = task.getCondition();
        // 将条件表达式编译为条件指令
        ConditionInstruction conIn = InstructionManager.getInstance()
                .createInstruction(InstructionType.CONDITION);
        if (con == null) {
            //otherwise 标签指令，条件永远为true
            conIn.setExpression("true");
        } else {
            //when指令
            conIn.setExpression(con.getExpression());
        }
        instSet.addInstruction(conIn);

        //指令开始位置
        int caseSize = instSet.size();

        // 处理所有的when分支
        for (ITask subTask : task.getSubTasks()) {
            // 编译子任务
            ITaskCompiler c = TaskConfigManager.getInstance().getTaskCompiler(
                    subTask.getTaskType());
            c.comipleTask(subTask, instSet);

        }
        // 追加附加的goto指令
        // 需要插入附加的goto指令，offset暂时以0代替
        GotoInstruction gotoIn = InstructionManager.getInstance().createInstruction(InstructionType.GOTO);
        instSet.addInstruction(gotoIn);
        
        // 设置条件表达式的作用域
        conIn.setGotoOffset(instSet.size() - caseSize);
    }

}
